{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<langgraph.graph.state.StateGraph at 0x2516bf8c760>"
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from typing import Annotated\n",
    "from langgraph.checkpoint.memory import MemorySaver\n",
    "# from langchain_anthropic import ChatAnthropic\n",
    "from customize.get_ollama import GetOllama\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "from langchain_core.messages import BaseMessage\n",
    "from typing_extensions import TypedDict\n",
    "from langchain_my_tools import bocha_tool\n",
    "from langgraph.graph import StateGraph, START, END\n",
    "from langgraph.graph.message import add_messages\n",
    "from langgraph.prebuilt import ToolNode, tools_condition\n",
    "\n",
    "\n",
    "class State(TypedDict):\n",
    "    messages: Annotated[list, add_messages]\n",
    "\n",
    "\n",
    "graph_builder = StateGraph(State)\n",
    "\n",
    "\n",
    "# tool = TavilySearchResults(max_results=2)\n",
    "tool = bocha_tool\n",
    "tools = [tool]\n",
    "#llm = ChatAnthropic(model=\"claude-3-5-sonnet-20240620\")\n",
    "llm = GetOllama(model_type=1)()\n",
    "llm_with_tools = llm.bind_tools(tools)\n",
    "\n",
    "\n",
    "memory = MemorySaver()\n",
    "def chatbot(state: State):\n",
    "    return {\"messages\": [llm_with_tools.invoke(state[\"messages\"])]}\n",
    "\n",
    "\n",
    "graph_builder.add_node(\"chatbot\", chatbot)\n",
    "\n",
    "tool_node = ToolNode(tools=[tool])\n",
    "graph_builder.add_node(\"tools\", tool_node)\n",
    "\n",
    "graph_builder.add_conditional_edges(\n",
    "    \"chatbot\",\n",
    "    tools_condition,\n",
    ")\n",
    "# Any time a tool is called, we return to the chatbot to decide the next step\n",
    "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
    "graph_builder.add_edge(START, \"chatbot\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [],
   "source": [
    "graph = graph_builder.compile(\n",
    "    checkpointer=memory,\n",
    "    # This is new!\n",
    "    interrupt_before=[\"tools\"],\n",
    "    # Note: can also interrupt __after__ tools, if desired.\n",
    "    # interrupt_after=[\"tools\"]\n",
    ")"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "data": {
      "text/plain": "IPython.core.display.Image"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import display, Image\n",
    "\n",
    "try:\n",
    "    img = Image(graph.get_graph().draw_mermaid_png())\n",
    "    display(Image)\n",
    "except Exception:\n",
    "    print(\"error\")\n",
    "    # This requires some extra dependencies and is optional\n",
    "    pass"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001B[1m Human Message \u001B[0m=================================\n",
      "\n",
      "I'm learning LangGraph. Could you do some research on it for me?\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "Tool Calls:\n",
      "  bochawebsearch (a9efff45-9bdc-49e7-9a51-8ce451b352b5)\n",
      " Call ID: a9efff45-9bdc-49e7-9a51-8ce451b352b5\n",
      "  Args:\n",
      "    query: LangGraph\n"
     ]
    }
   ],
   "source": [
    "user_input = \"I'm learning LangGraph. Could you do some research on it for me?\"\n",
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "# The config is the **second positional argument** to stream() or invoke()!\n",
    "events = graph.stream(\n",
    "    {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n",
    ")\n",
    "for event in events:\n",
    "    if \"messages\" in event:\n",
    "        event[\"messages\"][-1].pretty_print()"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "Tool Calls:\n",
      "  bochawebsearch (a9efff45-9bdc-49e7-9a51-8ce451b352b5)\n",
      " Call ID: a9efff45-9bdc-49e7-9a51-8ce451b352b5\n",
      "  Args:\n",
      "    query: LangGraph\n",
      "=================================\u001B[1m Tool Message \u001B[0m=================================\n",
      "Name: bochawebsearch\n",
      "\n",
      "机器之心报道\n",
      "编辑：张倩\n",
      "著名的大模型智能体工具，现在有大版本更新了。\n",
      "不知不觉，LangChain 已经问世一年了。作为一个开源框架，LangChain 提供了构建基于大模型的 AI 应用所需的模块和工具，大大降低了 AI 应用开发的门槛，使得任何人都可以基于 GPT-4 等大模型构建自己的创意应用。\n",
      "在过去的一年中，LangChain 自身也一直在进化。刚刚，LangChain 官方宣布，他们的首个稳定版本 ——LangChain v0.1.0 问世了。\n",
      "新版本有以下几个重要特点：\n",
      "可观察性：构建复杂的 LLM 应用是困难的。为了更好地进行调试，你需要知道采取的确切步骤以及每个步骤的输入 / 输出。通过与 LangSmith 的紧密集成，LangChain 在可观察性方面做到了业界领先；\n",
      "集成：拥有近 700 个集成，无论你想使用什么技术栈，LangChain 都能支持；\n",
      "可组合性：使用 LangChain 表达式语言，轻松创建任意 chain，为你带来数据编排框架的所有好处；\n",
      "流式处理：官方团队投入了大量精力，以确保所有使用 LangChain 表达式语言创建的 chain 都能...\n",
      "\n",
      "引言\n",
      "使用 AI 编码代理的应用程序激增。随着 LLM 质量的提高和推理成本的降低，构建有能力的 AI 代理只会变得越来越容易。最重要的是，工具生态系统正在迅速发展，使得构建复杂的 AI 编码代理变得更加容易。Langchain框架一直是这方面的领导者。它拥有创建生产就绪型 AI 应用程序所需的所有工具和技术。\n",
      "但到目前为止，它缺少一件事。这是具有周期性的多智能体协作。这对于解决复杂问题至关重要，因为在复杂问题中，问题可以被划分并委托给专门的代理。这就是 LangGraph 的用武之地，它是 Langchain 框架的一部分，旨在适应 AI 编码代理之间的多参与者有状态协作。此外，在本文中，我们将讨论 LangGraph 及其基本构建块，同时使用它构建代理。\n",
      "学习目标\n",
      "了解 LangGraph 是什么。\n",
      "探索用于构建有状态代理的 LangGraph 的基础知识。\n",
      "探索 TogetherAI 以访问 DeepSeekCoder 等开放获取模型。\n",
      "使用 LangGraph 构建 AI 编码代理来编写单元测试。\n",
      "本文是 作为数据科学博客马拉松的一部分发表的。\n",
      "什么是LangGraph？\n",
      "La...\n",
      "\n",
      "LangGraph概念全解\n",
      "智能体（Agent）\n",
      "随着LLM能力不断提升，越来越多系统开始接入LLM，让LLM成为系统中的一个关键组件。大家目前也都习惯把这些应用系统叫做智能体系统（Agentic），究竟什么是智能体系统呢？一个智能体系统应该具备什么能力？总体来说就是： 一个系统不再通过硬编码或者规则编码来控制工作流，而是让LLM来决定。\n",
      "特斯拉的自动驾驶系统早期一直依赖基于规则的算法。整个系统从车辆摄像头获取视觉数据，识别车道标记、行人、车辆、交通信号及8个摄像头范围内的所有事物，再应用一系列规则，比如红灯停、绿灯行、保持在车道线标记正中、不越过双黄线闯入对面车道等等，特斯拉的工程师编写了数十万行C++代码来来应对各种复杂的场景。直到史洛夫找到马斯克提出用AI来解决自动驾驶问题，后来他们发现，直接用AI来实现自动驾驶后，不仅直接可以删除那30多万行代码，而且整体运行速度比之前还快了10倍。\n",
      "整体来说，Agent目前主要体现在以下几个能力上：\n",
      "工具调用（Tool calling）：一般Agent识别用户意图后，常常需要调用工具来执行，获取工具结果\n",
      "采取行动（Action taking）...\n",
      "\n",
      "PART 01 预备知识\n",
      "【LangChain中的链与LCEL】\n",
      "Chain（链） 是LangChain中最核心的概念之一（看名字就知道）。简单的说，就是把自然语言输入、关联知识检索、Prompt组装、可用Tools信息、大模型调用、输出格式化等这些LLM 应用中的常见动作，组装成一个可以运行的“链”式过程。链可以直接调用，也可以用来进一步构建更强大的Agent。\n",
      "LCEL即LangChain Express Language， 即LangChain表达语言。这是LangChain提供的一种简洁的、用于组装上述“���”的声明性方式。\n",
      "我们看一个官方使用LCEL“组装”Chain的例子就明白：\n",
      "prompt = ChatPromptTemplate.from_template(\"讲一个关于 {topic} 的笑话\")model = ChatOpenAI(model=\"gpt-4\")output_parser = StrOutputParser()chain = prompt | model | output_parser#调用chainchain.invoke({\"topic\": \"冰淇淋...\n",
      "\n",
      "目录\n",
      "前言\n",
      "一、langgraph是什么？\n",
      "1.相关概念\n",
      "二、使用步骤\n",
      "1.引入库\n",
      "2.假设需求\n",
      "3.定义AgentState\n",
      "4.定义LLM\n",
      "5.定义节点方法\n",
      "6.节点、边添加\n",
      "7.编译执行\n",
      "8.优化\n",
      "9.条件边\n",
      "总结\n",
      "前言\n",
      "随着大模型能力的不断提升，大模型应用已经逐步从提示词到RAG再到智能体Agent过渡。Agent属于大模型高阶应用，但是受限于模型能力（思考规划等），智能体的稳定性存在很大的考验。为了解决这个问题，一个方向是提高大模型能力，再一个方向是预先将智能体执行过程进行编排，即工作流。\n",
      "本文就是要介绍智能体工作流框架langgraph，如何通过langgraph实现一个不错的智能体应用。\n",
      "一、langgraph是什么？\n",
      "langgraph是langchain官方推出的智能体工作流框架，该框架基于langchain、LECE，这样即可利用langchain的基础功能，从而可以更加高效的搭建出智能体工作流\n",
      "1.相关概念\n",
      "节点：可以理解为是一个独立的操作，每个节点可以和一个方法关联起来\n",
      "边：节点的连线，通过边将节点连接起来，以便将多个操作串联起来\n",
      "条件：有些节点到节点之间是有条...\n",
      "\n",
      "Hello folks，我是 Luga，今天我们来聊一下人工智能最新框架 - 用于构建循环状态多行为体代理系统的高效框架 - LangGraph\n",
      "LangGraph 作为 LangChain 的自然延伸，完美地填补了后者在构建复杂、动态的 AI 应用方面的空白。它为我们提供了一种全新的视角，让我们能够更轻松地创建智能代理，并将其应用于各种复杂的业务场景。\n",
      "何为 LangGraph ？以及 核心优势分析\n",
      "LangGraph 是 LangChain 生态系统中一颗崭新的创新之星，为构建基于 LLM （大语言模型）的有状态、多代理应用程序提供了一个全新的范式和强大的框架支持。作为一个专注于 AI 辅助开发的库，LangGraph 凭借其独特的设计理念和卓越的性能优势，在同类框架中脱颖而出，为技术开发者带来了前所未有的灵活性和可控性。\n",
      "与其他 LLM 框架相相比，LangGraph 最显著的特点在于其对循环（Cycles）流程的天然支持。在现实世界中，许多复杂的编程任务往往需要反复迭代、多次尝试才能完成，因此，代理的行为通常呈现出循环的特征。而传统的基于有向无环图（DAG）的解决方案无法很好地...\n",
      "\n",
      "▼最近直播超级多， 预约 保你有收获\n",
      "今天直播： 《RAG和GPTs构建Agent产业应用落地实战 》\n",
      "— 1 —\n",
      "LangGraph 技术架构解读\n",
      "LangGraph 是一个有用于构建有状态和多角色的 Agents 应用，它并不是一个独立于 Langchain 的新框架，而是基于 Langchain 之上构建的一个扩展库，可以与 Langchain 现有的链（Chains）、LangChain Expression Language（LCEL）等无缝协作。LangGraph 能够协调多个 Chain、Agent、Tool 等共同协作来完成输入任务，支持 LLM 调用“循环”和 Agent 过程的更精细化控制。\n",
      "LangGraph 的实现方式是把之前基于 AgentExecutor 的黑盒调用过程，用一种新的形式来构建：状态图（StateGraph）。把基于 LLM 的任务（比如：RAG、代码生成等）细节用 Graph 进行精确的定义（定义图的节点与边），最后基于这个图来编译生成应用。在任务运行过程中，维持一个中央状态对象(state)，会根据节点的跳转不断更新，状态包含的属性可自行定...\n",
      "\n",
      "单个Agent使用少量的工具通常是高效的，但是即便强大如gpt-4，在使用多个工具的时候，效果也会大大折扣。\n",
      "“分而治之”的方式可以更容易完成任务。为每个任务或者每个领域单独创建一个Agent，然后将任务分发给给正确的“专家”(处理特定任务的Agent)。\n",
      "下面的nootbook展示了如何使用LangGraph实现多Agent方式，多Agent组成的最图结果大概是下面这样的：\n",
      "在正式开始介绍之前，多说一句：这里主要介绍如何使用LangGraph实现多Agent的某些设计模式，如果这个设计模式恰好是你需要的，我们推荐你将它和本文档介绍的其他模式结合起来是使用，这个可以获得更好的性能。\n",
      "## 准备基础环境\n",
      "```Bash\n",
      "%%capture --no-stderr\n",
      "%pip install -U langchain langchain_openai langsmith pandas langchain_experimental matplotlib langgraph langchain_core\n",
      "```\n",
      "代码中引入环境变量\n",
      "```Bash\n",
      "import getpass\n",
      "import os...\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "\n",
      "从上述信息来看，LangGraph 是 LangChain 生态系统的一部分，旨在支持构建具有状态和多代理的应用程序。以下是关于 LangGraph 的几个关键点：\n",
      "\n",
      "1. **概念与背景**：\n",
      "   - LangGraph 是基于 LangChain 构建的一个扩展库，用于处理复杂的、动态的 AI 应用。\n",
      "   - 它特别强调了对循环（Cycles）的支持，使得构建需要多次迭代或尝试的任务变得更加容易。\n",
      "\n",
      "2. **核心优势分析**：\n",
      "   - 通过状态图（StateGraph）来精确定义任务中的节点和边，从而能够更精细地控制基于LLM的任务流程。\n",
      "   - 支持多Agent协作，可以将复杂的任务分解为多个独立的Agent执行，每个Agent专注于特定领域的任务。\n",
      "\n",
      "3. **技术架构解读**：\n",
      "   - LangGraph 通过状态图来描述任务流程，这种表示方式允许更灵活和精确地定义代理行为及其交互。\n",
      "   - 它能够协调多个链（Chains）、Agent、工具等共同协作完成输入任务，支持LLM调用“循环”和Agent过程的更精细化控制。\n",
      "\n",
      "4. **实践应用**：\n",
      "   - 通过示例展示了如何使用LangGraph实现多Agent方式，并构建复杂的应用场景。\n",
      "   - 提供了一个完整的环境配置指南以及代码片段来帮助用户快速开始使用 LangGraph。\n",
      "\n",
      "5. **学习资源与工具**：\n",
      "   - 提供了相关直播和教程链接，例如《RAG和GPTs构建Agent产业应用落地实战》，可以帮助开发者更深入地了解如何具体实现 LangGraph 的功能。\n",
      "   \n",
      "为了进一步深入了解 LangGraph 和LangChain的具体用法，建议阅读相关的官方文档或参考提供的教程示例。同时，尝试使用这些工具在实际项目中进行实践也是一个不错的选择。如果有特定的技术问题或者需要具体的代码帮助，请随时告知！\n"
     ]
    }
   ],
   "source": [
    "# `None` will append nothing new to the current state, letting it resume as if it had never been interrupted\n",
    "events = graph.stream(None, config, stream_mode=\"values\")\n",
    "for event in events:\n",
    "    if \"messages\" in event:\n",
    "        event[\"messages\"][-1].pretty_print()"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
